﻿#region

using System;
using System.IO;
using System.Security.Principal;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using Mvc.Mailer;
using Recaptcha;
using log4net;
using xConnected.Core.Interfaces.Data;
using xConnected.Core.Interfaces.Service;
using xConnected.Core.Model;
using xConnected.Core.Model.ViewModel;
using xConnected.Infrastructure;
using xConnected.Mailers;

#endregion

namespace xConnected.Controllers
{
    public class AccountController : MainController
    {
        protected ICompanyProfileService CompanyService;
        protected IExpertProfileService ProfileService;

        protected IUnitOfWork UnitOfWork;
        protected IUserService UserService;

        public AccountController(IUserService userService, IExpertProfileService profileService,
                                 ICompanyProfileService companyService, IUnitOfWork unitOfWork)
        {
            UserService = userService;
            ProfileService = profileService;
            CompanyService = companyService;
            UnitOfWork = unitOfWork;
        }

        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult SendWelcomeMessage(RegisterModel registerModel)
        {
            ILog log = LogManager.GetLogger(GetType());
            try
            {
                var mailer = new UserMailer();
                var user = UserService.GetUserByEmail(registerModel.Email);
                var msg = mailer.Welcome(user.Email, user.Username, user.ActivationKey);
                msg.Send();
                return Content("Ok");
            }
            catch (Exception ex)
            {
                log.Error(ex.Message + Environment.NewLine + "Stack: " + ex.StackTrace, ex);
                return Content("ERROR");
            }
        }


        public ActionResult Confirmation()
        {
            return View();
        }

        [HttpPost]
        public JsonResult SignIn(LogOnModel logOn, string returnUrl = null)
        {
            ILog log = LogManager.GetLogger(GetType());
            try
            {
                var user = UserService.GetUserByUsername(logOn.Username);
                if (user != null)
                {
                    if (user.Password == logOn.Password)
                    {
                        if (user.IsActivated)
                        {
                            LogOn(user, logOn.RememberMe);

                            //if (string.IsNullOrWhiteSpace(returnUrl) || returnUrl == "/")
                            //{
                            //    return RedirectToAction("Index", "Home");
                            //}

                            return Json(new {message = "Ok."}, JsonRequestBehavior.AllowGet);
                        }

                        return Json(new {message = "Your account is not activated. Please activate your account."},
                                    JsonRequestBehavior.AllowGet);
                    }

                    return Json(new {message = "Password doesn't match."}, JsonRequestBehavior.AllowGet);
                }

                return Json(new {message = "User doesn't exist."}, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                log.Error(ex.Message + Environment.NewLine + "Stack: " + ex.StackTrace, ex);
                return Json(new {Result = "ERROR", ex.Message}, JsonRequestBehavior.AllowGet);
            }
        }

        protected internal void LogOn(User user, bool rememberMe)
        {
            var principal = new GenericPrincipal(new GenericIdentity(user.Username), new string[] {});

            if (System.Web.HttpContext.Current != null)
            {
                DateTime expires = DateTime.Now.AddDays(20);
                var ticket = new FormsAuthenticationTicket(
                    1, // Version
                    user.Username, // Username
                    DateTime.Now, // Creation
                    expires, // Expiration
                    rememberMe, // Persistent
                    user.SerializeForTicket()
                    );
                string encryptedTicket = FormsAuthentication.Encrypt(ticket);
                var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
                if (ticket.IsPersistent)
                    authCookie.Expires = expires;
                Response.Cookies.Add(authCookie);

            }
            else
            {
                Thread.CurrentPrincipal = principal;
            }
        }

        [HttpPost]
        public ActionResult SignOut()
        {
            ILog log = LogManager.GetLogger(GetType());
            try
            {
                if (System.Web.HttpContext.Current != null)
                {
                    FormsAuthentication.SignOut();
                  
                    System.Web.HttpContext.Current.User = null;
                }
                else
                {
                    Thread.CurrentPrincipal = null;
                }

                return RedirectToAction("Index", "Home");
            }
            catch (Exception ex)
            {
                log.Error(ex.Message + Environment.NewLine + "Stack: " + ex.StackTrace, ex);
                return Content("ERROR");
            }
        }

        

        [HttpPost]
        [RecaptchaControlMvc.CaptchaValidatorAttribute]
        public JsonResult Register(RegisterModel register, bool captchaValid)
        {
            ILog log = LogManager.GetLogger(GetType());
            try
            {
                if (captchaValid)
                {
                    var emailUsed = UserService.GetUserByEmail(register.Email) != null;
                    if (emailUsed)
                    {
                        return Json(new {message = "This email already exists. Please enter new email."},
                                    JsonRequestBehavior.AllowGet);
                    }


                    var user = new User
                                   {
                                       Email = register.Email,
                                       Password = register.Password,
                                       Username = register.Username,
                                       ActivationKey = Guid.NewGuid()
                                   };

                    UserService.SaveOrUpdate(user);
                    UnitOfWork.Commit();

                    // create the directory structure
                    var di1 =
                        new DirectoryInfo(Server.MapPath("~/Content/Uploads/" + user.Username));
                    di1.Create();

                    var di2 =
                      new DirectoryInfo(Server.MapPath("~/Content/Uploads/" + Path.Combine(user.Username, "ExpertProfiles")));
                    di2.Create();

                    var di3 =
                      new DirectoryInfo(Server.MapPath("~/Content/Uploads/" + Path.Combine(user.Username, "CompanyProfiles")));
                    di3.Create();

                    return Json(new {message = "Ok."}, JsonRequestBehavior.AllowGet);
                }

                return Json(new {message = "Please type again, the two words bellow."}, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                log.Error(ex.Message + Environment.NewLine + "Stack: " + ex.StackTrace, ex);
                return Json(new {Result = "ERROR", ex.Message}, JsonRequestBehavior.AllowGet);
            }
        }
    }
}